{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Model: K Nearest Neighbors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Importing Libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import _pickle as pickle\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import precision_score, recall_score, accuracy_score, f1_score, confusion_matrix, classification_report\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "# Importing the model\n",
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Loading in Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_excel('../top10_corr_features.xlsx')\n",
    "df = df.drop(df.columns[0], axis = 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scaling the Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaler = StandardScaler()\n",
    "\n",
    "features_df = df.drop([\"Decision\"], 1)\n",
    "\n",
    "scaled_df = pd.DataFrame(scaler.fit_transform(features_df), \n",
    "                               index=features_df.index, \n",
    "                               columns=features_df.columns)\n",
    "\n",
    "df = scaled_df.join(df.Decision)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Splitting the Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = df.drop([\"Decision\"], 1)\n",
    "y = df.Decision\n",
    "\n",
    "# Train, test, split\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Helper Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Function for plotting confusion matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_confusion_matrix(y_true, y_pred, labels=[\"Sell\", \"Buy\", \"Hold\"], \n",
    "                          normalize=False, title=None, cmap=plt.cm.coolwarm):\n",
    "\n",
    "    cm = confusion_matrix(y_true, y_pred)\n",
    "    fig, ax = plt.subplots(figsize=(12,6))\n",
    "    im = ax.imshow(cm, interpolation='nearest', cmap=cmap)\n",
    "    ax.figure.colorbar(im, ax=ax)\n",
    "    # We want to show all ticks...\n",
    "    ax.set(xticks=np.arange(cm.shape[1]),\n",
    "           yticks=np.arange(cm.shape[0]),\n",
    "           # ... and label them with the respective list entries\n",
    "           xticklabels=labels, yticklabels=labels,\n",
    "           title=title,\n",
    "           ylabel='ACTUAL',\n",
    "           xlabel='PREDICTED')\n",
    "    # Rotate the tick labels and set their alignment.\n",
    "    plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\",\n",
    "             rotation_mode=\"anchor\")\n",
    "    # Loop over data dimensions and create text annotations.\n",
    "    fmt = '.2f' if normalize else 'd'\n",
    "    thresh = cm.max() / 1.5\n",
    "    for i in range(cm.shape[0]):\n",
    "        for j in range(cm.shape[1]):\n",
    "            ax.text(j, i, format(cm[i, j], fmt),\n",
    "                    ha=\"center\", va=\"center\",\n",
    "                    color=\"snow\" if cm[i, j] > thresh else \"orange\",\n",
    "                    size=26)\n",
    "    ax.grid(False)\n",
    "    fig.tight_layout()\n",
    "    return ax"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Modeling\n",
    "The preferred evaluation metric used will be __Precision__ for each class.  They will be optimized using the __F1 Score-Macro-Average__ to balance the Precision and Recall.  This is done because we want to not only be correct when predicting but also make a decent amount of predictions for each class.  Classes such as 'Buy' and 'Sell' are more important than 'Hold'."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fitting and Training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,\n",
       "                     weights='uniform')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Fitting and training\n",
    "clf = KNeighborsClassifier()\n",
    "clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Printing out Evaluation Metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "        Sell       0.36      0.67      0.47         6\n",
      "         Buy       0.60      0.33      0.43         9\n",
      "        Hold       0.00      0.00      0.00         2\n",
      "\n",
      "    accuracy                           0.41        17\n",
      "   macro avg       0.32      0.33      0.30        17\n",
      "weighted avg       0.45      0.41      0.39        17\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Classifier predictions\n",
    "pred = clf.predict(X_test)\n",
    "\n",
    "#Printing out results\n",
    "report = classification_report(y_test, pred, target_names=['Sell', 'Buy', 'Hold'])\n",
    "print(report)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Confusion Matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_confusion_matrix(y_test, pred, title=\"Confusion Matrix\")\n",
    "np.set_printoptions(precision=1)\n",
    "# Plot non-normalized confusion matrix\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tuning Model Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Parameters to Tune\n",
    "params = {\"n_neighbors\": [10, 15, 20],\n",
    "          \"weights\": ['uniform', 'distance'],\n",
    "          \"p\": [1,2]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 3 folds for each of 12 candidates, totalling 36 fits\n",
      "[CV] n_neighbors=10, p=1, weights=uniform ............................\n",
      "[CV]  n_neighbors=10, p=1, weights=uniform, score=(train=0.365, test=0.286), total=   0.0s\n",
      "[CV] n_neighbors=10, p=1, weights=uniform ............................\n",
      "[CV]  n_neighbors=10, p=1, weights=uniform, score=(train=0.378, test=0.292), total=   0.0s\n",
      "[CV] n_neighbors=10, p=1, weights=uniform ............................\n",
      "[CV]  n_neighbors=10, p=1, weights=uniform, score=(train=0.415, test=0.387), total=   0.0s\n",
      "[CV] n_neighbors=10, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=10, p=1, weights=distance, score=(train=1.000, test=0.243), total=   0.0s\n",
      "[CV] n_neighbors=10, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=10, p=1, weights=distance, score=(train=1.000, test=0.239), total=   0.0s\n",
      "[CV] n_neighbors=10, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=10, p=1, weights=distance, score=(train=1.000, test=0.333), total=   0.0s\n",
      "[CV] n_neighbors=10, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=10, p=2, weights=uniform, score=(train=0.404, test=0.278), total=   0.0s\n",
      "[CV] n_neighbors=10, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=10, p=2, weights=uniform, score=(train=0.382, test=0.292), total=   0.0s\n",
      "[CV] n_neighbors=10, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=10, p=2, weights=uniform, score=(train=0.374, test=0.339), total=   0.0s\n",
      "[CV] n_neighbors=10, p=2, weights=distance ...........................\n",
      "[CV]  n_neighbors=10, p=2, weights=distance, score=(train=1.000, test=0.313), total=   0.0s\n",
      "[CV] n_neighbors=10, p=2, weights=distance ...........................\n",
      "[CV]  n_neighbors=10, p=2, weights=distance, score=(train=1.000, test=0.256), total=   0.0s\n",
      "[CV] n_neighbors=10, p=2, weights=distance ...........................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "[Parallel(n_jobs=1)]: Done   2 out of   2 | elapsed:    0.0s remaining:    0.0s\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "[Parallel(n_jobs=1)]: Done   3 out of   3 | elapsed:    0.0s remaining:    0.0s\n",
      "[Parallel(n_jobs=1)]: Done   4 out of   4 | elapsed:    0.0s remaining:    0.0s\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  n_neighbors=10, p=2, weights=distance, score=(train=1.000, test=0.348), total=   0.0s\n",
      "[CV] n_neighbors=15, p=1, weights=uniform ............................\n",
      "[CV]  n_neighbors=15, p=1, weights=uniform, score=(train=0.278, test=0.233), total=   0.0s\n",
      "[CV] n_neighbors=15, p=1, weights=uniform ............................\n",
      "[CV]  n_neighbors=15, p=1, weights=uniform, score=(train=0.274, test=0.195), total=   0.0s\n",
      "[CV] n_neighbors=15, p=1, weights=uniform ............................\n",
      "[CV]  n_neighbors=15, p=1, weights=uniform, score=(train=0.394, test=0.369), total=   0.0s\n",
      "[CV] n_neighbors=15, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=15, p=1, weights=distance, score=(train=1.000, test=0.254), total=   0.0s\n",
      "[CV] n_neighbors=15, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=15, p=1, weights=distance, score=(train=1.000, test=0.256), total=   0.0s\n",
      "[CV] n_neighbors=15, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=15, p=1, weights=distance, score=(train=1.000, test=0.370), total=   0.0s\n",
      "[CV] n_neighbors=15, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=15, p=2, weights=uniform, score=(train=0.267, test=0.233), total=   0.0s\n",
      "[CV] n_neighbors=15, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=15, p=2, weights=uniform, score=(train=0.345, test=0.195), total=   0.0s\n",
      "[CV] n_neighbors=15, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=15, p=2, weights=uniform, score=(train=0.375, test=0.339), total=   0.0s\n",
      "[CV] n_neighbors=15, p=2, weights=distance ...........................\n",
      "[CV]  n_neighbors=15, p=2, weights=distance, score=(train=1.000, test=0.238), total=   0.0s\n",
      "[CV] n_neighbors=15, p=2, weights=distance ...........................\n",
      "[CV]  n_neighbors=15, p=2, weights=distance, score=(train=1.000, test=0.243), total=   0.0s\n",
      "[CV] n_neighbors=15, p=2, weights=distance ...........................\n",
      "[CV]  n_neighbors=15, p=2, weights=distance, score=(train=1.000, test=0.378), total=   0.0s\n",
      "[CV] n_neighbors=20, p=1, weights=uniform ............................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  n_neighbors=20, p=1, weights=uniform, score=(train=0.278, test=0.208), total=   0.0s\n",
      "[CV] n_neighbors=20, p=1, weights=uniform ............................\n",
      "[CV]  n_neighbors=20, p=1, weights=uniform, score=(train=0.384, test=0.268), total=   0.0s\n",
      "[CV] n_neighbors=20, p=1, weights=uniform ............................\n",
      "[CV]  n_neighbors=20, p=1, weights=uniform, score=(train=0.325, test=0.251), total=   0.0s\n",
      "[CV] n_neighbors=20, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=20, p=1, weights=distance, score=(train=1.000, test=0.208), total=   0.0s\n",
      "[CV] n_neighbors=20, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=20, p=1, weights=distance, score=(train=1.000, test=0.243), total=   0.0s\n",
      "[CV] n_neighbors=20, p=1, weights=distance ...........................\n",
      "[CV]  n_neighbors=20, p=1, weights=distance, score=(train=1.000, test=0.359), total=   0.0s\n",
      "[CV] n_neighbors=20, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=20, p=2, weights=uniform, score=(train=0.298, test=0.254), total=   0.0s\n",
      "[CV] n_neighbors=20, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=20, p=2, weights=uniform, score=(train=0.405, test=0.268), total=   0.0s\n",
      "[CV] n_neighbors=20, p=2, weights=uniform ............................\n",
      "[CV]  n_neighbors=20, p=2, weights=uniform, score=(train=0.338, test=0.309), total=   0.0s\n",
      "[CV] n_neighbors=20, p=2, weights=distance ...........................\n",
      "[CV]  n_neighbors=20, p=2, weights=distance, score=(train=1.000, test=0.254), total=   0.0s\n",
      "[CV] n_neighbors=20, p=2, weights=distance ...........................\n",
      "[CV]  n_neighbors=20, p=2, weights=distance, score=(train=1.000, test=0.293), total=   0.0s\n",
      "[CV] n_neighbors=20, p=2, weights=distance ...........................\n",
      "[CV]  n_neighbors=20, p=2, weights=distance, score=(train=1.000, test=0.436), total=   0.0s\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "[Parallel(n_jobs=1)]: Done  36 out of  36 | elapsed:    0.4s finished\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\model_selection\\_search.py:813: DeprecationWarning: The default of the `iid` parameter will change from True to False in version 0.22 and will be removed in 0.24. This will change numeric results when test-set sizes are unequal.\n",
      "  DeprecationWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=3, error_score='raise-deprecating',\n",
       "             estimator=KNeighborsClassifier(algorithm='auto', leaf_size=30,\n",
       "                                            metric='minkowski',\n",
       "                                            metric_params=None, n_jobs=None,\n",
       "                                            n_neighbors=5, p=2,\n",
       "                                            weights='uniform'),\n",
       "             iid='warn', n_jobs=None,\n",
       "             param_grid={'n_neighbors': [10, 15, 20], 'p': [1, 2],\n",
       "                         'weights': ['uniform', 'distance']},\n",
       "             pre_dispatch='2*n_jobs', refit=True, return_train_score=True,\n",
       "             scoring='f1_macro', verbose=5)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "search = GridSearchCV(clf, params, cv=3, return_train_score=True, verbose=5, scoring='f1_macro')\n",
    "\n",
    "search.fit(X,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tuned Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean Training Score: 0.6744194795654823\n",
      "Mean Testing Score: 1.0\n",
      "\n",
      "Best Parameter Found:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'n_neighbors': 20, 'p': 2, 'weights': 'distance'}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(\"Mean Training Score:\", np.mean(search.cv_results_['mean_train_score']))\n",
    "print(\"Mean Testing Score:\", search.score(X, y))\n",
    "print(\"\\nBest Parameter Found:\")\n",
    "search.best_params_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Model with the Best Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "                     metric_params=None, n_jobs=None, n_neighbors=20, p=2,\n",
       "                     weights='distance')"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "search_clf = search.best_estimator_\n",
    "\n",
    "search_clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Results from Optimum Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "        Sell       0.29      0.33      0.31         6\n",
      "         Buy       0.40      0.44      0.42         9\n",
      "        Hold       0.00      0.00      0.00         2\n",
      "\n",
      "    accuracy                           0.35        17\n",
      "   macro avg       0.23      0.26      0.24        17\n",
      "weighted avg       0.31      0.35      0.33        17\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    }
   ],
   "source": [
    "# Classifier predictions\n",
    "s_pred = search_clf.predict(X_test)\n",
    "\n",
    "#Printing out results\n",
    "report = classification_report(y_test, s_pred, target_names=['Sell', 'Buy', 'Hold'])\n",
    "print(report)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Confusion Matrix for Optimum Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_confusion_matrix(y_test, s_pred, title=\"Confusion Matrix\")\n",
    "np.set_printoptions(precision=1)\n",
    "# Plot non-normalized confusion matrix\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
